package com.shujing.service.impl;

import com.shujing.constant.MessageConstant;
import com.shujing.dto.PasswordDTO;
import com.shujing.exception.LoginFailedException;
import com.shujing.mapper.UserMapper;
import com.shujing.pojo.User;
import com.shujing.service.UserService;
import com.shujing.utils.JwtUtil;
import com.shujing.utils.Md5Util;
import com.shujing.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestHeader;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author 陈书憬
 * @version 1.0
 * 2024/4/8
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 该接口用于注册新用户
     *
     * @param username
     * @param password
     */
    @Override
    public User findByName(String username, String password) {
        // 先查询该名字是否存在
        User user = userMapper.selectByName(username);

        if (user == null) {
            //加密
            String password1 = Md5Util.getMD5String(password);
            // 如果不存在则插入数据
            userMapper.insertUser(username, password1);
        }
        return user;
    }

    /**
     * 该接口用于登录
     *
     * @param username
     * @param password
     * @return
     */
    @Override
    public String login(String username, String password) {
        // 根据用户名查询用户
        User loginUser = userMapper.selectByName(username);
        // 判断该用户是否存在
        if (loginUser == null) {
            // 该用户不存在
            throw new LoginFailedException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        // 验证登录密码是否正确
        if (!Md5Util.getMD5String(password).equals(loginUser.getPassword())) {
            // 密码错误
            throw new LoginFailedException(MessageConstant.PASSWORD_ERROR);
        }
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", loginUser.getId());
        claims.put("username", loginUser.getUsername());

        String token = JwtUtil.genToken(claims);
        // 把token存储到redis中
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        operations.set(token, token, 1, TimeUnit.HOURS);

        return token;
    }

    /**
     * 获取用户详细信息
     *
     * @param username
     * @return
     */
    @Override
    public User userInfo(String username) {
        User user = userMapper.selectByName(username);
        return user;
    }

    /**
     * 更新用户基本信息
     *
     * @param user
     * @return
     */
    @Override
    public void update(User user) {
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateUserInfo(user);
    }

    /**
     * 更新用户密码
     *
     * @param passwordDTO
     */
    @Override
    public void updatePassword(PasswordDTO passwordDTO) {
        // 判断传入参数是否为空
        if (passwordDTO.getOld_pwd() == null || passwordDTO.getOld_pwd().isEmpty() &&
                passwordDTO.getNew_pwd() == null || passwordDTO.getNew_pwd().isEmpty() &&
                passwordDTO.getRe_pwd() == null || passwordDTO.getRe_pwd().isEmpty()) {
            throw new LoginFailedException(MessageConstant.NULL_PASSWORD_ERROR);
        }

        // 把传入的密码进行加密
        String oldPwd = Md5Util.getMD5String(passwordDTO.getOld_pwd());
        String newPwd = Md5Util.getMD5String(passwordDTO.getNew_pwd());
        String rePwd = Md5Util.getMD5String(passwordDTO.getRe_pwd());

        // 获取当前用户id
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get("id");

        // 拿到原本的密码,校验拿到的密码是否一致 输入当前id得到密码 此刻的密码为加密过的密码
        User user = userMapper.list(userId);
        String password = user.getPassword();


        if (!password.equals(oldPwd)) {
            throw new LoginFailedException(MessageConstant.PASSWORD_ERROR);
        }

        // 校验输入的两次是否正确
        if (!newPwd.equals(rePwd)) {
            throw new LoginFailedException(MessageConstant.TWO_PASSWORD_ERROR);
        }

        // 新密码和原始密码一样
        if (password.equals(newPwd)) {
            throw new LoginFailedException(MessageConstant.NEW_OLD_PASSWORD_ERROR);
        }

        user.setPassword(newPwd);
        user.setUpdateTime(LocalDateTime.now());
        // 如果正确直接update，修改密码
        userMapper.updateUserInfo(user);
    }
}
